home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-21
/
printit2.zip
/
PRINTIT.ASM
< prev
next >
Wrap
Assembly Source File
|
1992-05-11
|
16KB
|
493 lines
title PRINTIT.COM A program that just copies a file to LPT1
comment *
This program just copies a file or files to LPT1. It DOES NOT
check to see if LPT1 is ready, and will loop endlessly if LPT1
is not ready. Mostly for use under Desqview since "copy filename
lpt1" is an internal command, and DV will not do much in the middle
of an internal command.
PRINTIT inserts a form feed between files and after the last file
printed.
Usage:
PRINTIT filespec
"filespec" may include a path and/or wildcard characters.
To create PRINTIT.COM:
MASM PRINTIT;
LINK PRINTIT;
EXE2BIN PRINTIT.EXE PRINTIT.COM
This program is released into the public domain.
Jon Fleming (BIX jfleming)
Version 1.0: 9/28/88
Revised 5/11/92 version 2.0: see the READ.ME file
*
buffer_size equ 10240 ;Nice fat 10K buffer for file reads.
; Must be at least 256.
stack_size equ 256
cr equ 0dh
lf equ 0ah
tab equ 9
TRUE equ 1
FALSE equ 0
stack segment stack ;just to keep the linker quiet
stack ends
code segment
data segment byte
bad_memory_message db cr,lf,"Not enough memory",cr,lf,"$"
no_filespec_message db cr,lf,"No file specified",cr,lf,"$"
no_file_found_message db cr,lf,"No matching file found",cr,lf,"$"
cant_open_message db cr,lf,"Can't open file",cr,lf,"$"
user_prompt_message db cr,lf,"Filespec to print (<Enter> to quit): $"
curr_dir_message db cr,lf,"Default directory is: $"
end_error_message db "Press any key to continue ...$"
at_end_of_file db FALSE
desqview_present db FALSE
filename_start dw ? ;pointer to first character after path
chars_in_buffer dw ?
file_handle dw ?
curr_drive db " :\$"
;file name as typed on the command line
cmd_line_file_name label byte
db 7Fh ; 127 characters max user input
;here we get a little tricky; the following uninitialized data is done
; this way so we don't need room for it in the disk file PRINTIT.COM
;path + file name returned by DOS find-file
full_file_name equ cmd_line_file_name
;Disk Transfer Area
DTA equ cmd_line_file_name + 128
found_file_name equ DTA + 30
;buffer for reading from the file
buffer equ DTA + 128
end_buffer equ buffer + buffer_size + 1
data ends
program group code, data
org 80h ;command tail in the PSP
cmd_tail_length db ?
cmd_tail db ?
org 100h
assume cs:program,ds:program,es:program,ss:program
begin:
cld
mov bx, offset program:end_buffer
add bx,stack_size ;locate end of program
cmp sp,bx
jae ok_to_move_stack
mov dx,offset program:bad_memory_message
jmp error_exit
ok_to_move_stack:
cli
mov sp,bx ;relocate stack
sti
add bx,15
mov cl,4
shr bx,cl ;program size in paragraphs
mov ah,4ah
int 21h ;release unused memory
jnc memory_ok ;If we didn't have that much memory,
; DOS reports an error
mov dx,offset program:bad_memory_message
jmp error_exit
memory_ok:
mov cx,"DE"
mov dx,"SQ"
mov ax,2b01h
int 21h ; Check if Desqview is present
cmp al,0ffh
je check_command_tail
mov desqview_present,TRUE ; Desqview's here, save for later
check_command_tail:
call scan_cmd_tail ;get filespec to print
jnc something_present ;there's SOMETHING on the command line
mov ah,09h ; Nothing on the command line,
mov dx,offset program:curr_dir_message
int 21h
mov ah,19h
int 21h ; Get the current drive number
add al,41h ; Convert it to an uppercase letter
mov curr_drive,al ; And store it away
mov ah,09h
mov dx, offset program:curr_drive
int 21h ; Print the current drive
mov ah,47h
xor dl,dl
mov si,offset program:buffer
int 21h ; Get the current default directory
mov di,offset program:buffer
xor al,al
mov cx,0ffh
cld
repne scasb ; Locate the zero-terminator
dec di
mov al,"$"
stosb ; Replace it with a "$"
mov ah,09h
mov dx,offset program:buffer
int 21h ; Display default directory
mov ah,09h
mov dx,offset program:user_prompt_message
int 21h ; Ask the user for a filespec
mov ah,0Ah
mov dx,offset program:cmd_line_file_name
int 21h ; Get the user's input
mov cl,cmd_line_file_name+1
xor ch,ch
push cx ; Save count of amount of input
or cl,cl
jnz bump_user_input_over
jmp normal_exit ; If no input, quit
bump_user_input_over:
mov di,offset program:cmd_line_file_name
mov si,di
inc si
inc si
cld
rep movsb ; Shift the user's input over two to
; cover the max input count and
; actual input count
pop cx ; Remember the count of input
mov si,offset program:cmd_line_file_name ; Restore pointer
; to start of filespec
jmp short filespec_present
something_present:
or al,al ;is it a switch?
jz filespec_present
mov dx,offset program:no_filespec_message
jmp short error_exit
filespec_present: ; Now let's move the file to another
; buffer so we can handle wild cards
mov ax,offset program:full_file_name
mov filename_start,ax ;initialize pointer to start of
;file name
mov di,offset program:cmd_line_file_name
move_filename:
lodsb
stosb
cmp al,":" ;check for end-of-path characters
je update_pointer_to_start
cmp al,"\"
jne end_move_filename_loop
update_pointer_to_start:
mov filename_start,di
end_move_filename_loop:
loop move_filename
xor al,al
stosb ;make it null-terminated
mov dx,offset program:DTA
mov ah,1ah
int 21h ;set up our Disk Transfer Area
mov cx,00100011b ;normal, archive, hidden, or read-only attributes
mov ah,4eh
mov dx,offset program:full_file_name
int 21h ;search for first matching file
jnc ready_to_print ;found one
mov dx,offset program:no_file_found_message
error_exit:
mov ah,9
int 21h ;print error message
cmp desqview_present, TRUE ; Is desqview around?
jne actual_error_exit ; Nope
mov ah,9 ; Yup, print a message ...
mov dx,offset program:end_error_message
int 21h
mov ah,07h ; And wait for the user to hit a key
int 21h ; so the window doesn't close
actual_error_exit:
mov ax,4c01h
int 21h ;terminate, return code 1
ready_to_print:
mov si,offset program:found_file_name
mov di,filename_start
construct_full_name:
lodsb
stosb ;append file name to path (if there is
; one)
or al,al ;hit the end?
jz open_file ;yep
jmp construct_full_name ;nope
open_file:
mov ax,3d00h
mov dx,offset program:full_file_name
int 21h ;open the file
jnc opened_file ;if a path was included, a match will
;be found, but this simple-minded
;OPEN won't work
mov dx,offset program:cant_open_message
jmp error_exit
opened_file:
mov file_handle,ax ;save handle
mov at_end_of_file,FALSE ;initialize EOF flag
read_into_buffer:
mov bx,file_handle
mov cx,buffer_size
mov dx,offset program:buffer
mov ah,3fh
int 21h ;read into buffer
mov chars_in_buffer, ax ;save actual number of chars read
cmp ax,buffer_size ;got a full buffer?
je prepare_to_print ;yep
mov at_end_of_file, TRUE ;nope, must be at end of file
prepare_to_print:
mov si,offset program:buffer
mov cx,chars_in_buffer
jcxz look_for_next_file ;skip if buffer empty (file size is
; a multiple of buffer size)
print_loop:
lodsb
mov dl,al ;next character
mov ah,5
int 21h ;print it
loop print_loop
cmp at_end_of_file,TRUE ;more characters?
jne read_into_buffer
look_for_next_file:
mov bx,file_handle
mov ah,3eh
int 21h ;close the current file
mov dl,12
mov ah,5
int 21h ;form feed between files or @ end
mov ah,4fh
int 21h ;search for next matching file
jc normal_exit ;none found, all done
jmp ready_to_print ;found another file, go print it
normal_exit:
mov ax,4c00h
int 21h ;terminate, return code 0
current_cmd_tail_position dw 0 ;storage for use by
characters_left_in_cmd_tail db 0ffh ;scan_cmd_tail
scan_cmd_tail proc near
;procedure to get parameters off the command line. If no more parameters
;are present, returns carry set. If the next parameter is a switch (prefixed
;by "/" or "-"), the switch is returned in AL (converted to uppercase) and
;SI will point to the first character after the switch.
;Otherwise, AL will be zero; SI will point to the beginning of the
;parameter; and CX will contain the length of the parameter. In any case,
;SI, AH and CX are destroyed
push dx
clc ;assume more characters in tail
cmp characters_left_in_cmd_tail,0ffh ;assuming the command
jne not_first_call ;tail isn't ever really this long
mov al,cmd_tail_length
inc al ;include <return> in count
mov characters_left_in_cmd_tail,al
mov ax,offset program:cmd_tail ;initialize our variables
mov current_cmd_tail_position,ax
mov cl,cmd_tail_length
xor ch,ch
jcxz no_more_parameters
mov si,ax ;set up to capitalize the
mov di,ax ;entire command tail
capitalize_cmd_tail_loop:
lodsb
cmp al,'a'
jb end_capitalize_loop
cmp al,'z'
ja end_capitalize_loop
and al,0dfh ;convert to uppercase
end_capitalize_loop:
stosb
loop capitalize_cmd_tail_loop
not_first_call:
mov cl,characters_left_in_cmd_tail
xor ch,ch
jcxz no_more_parameters
mov si,current_cmd_tail_position
scan_tail_loop:
lodsb ;get next character
dec cx
cmp al,' ' ;see if it's whitespace
je scan_tail_loop
cmp al,tab
je scan_tail_loop
cmp al,cr ;check for end of tail
je no_more_parameters
cmp al,'/' ;found something, is it a switch?
je found_a_switch
cmp al,'-'
je found_a_switch
call scan_a_non_switch ;it's not a switch, scan it
inc cx ;correct character count
xor al,al ;flag that a non-switch was found
jmp short finished_scan_cmd_tail
found_a_switch:
lodsb ;get the switch
dec cx
push ax ;save it
call scan_a_non_switch ;get any trailing string
pop ax ;restore switch
inc si ;make SI point to trailing chars
jmp short finished_scan_cmd_tail
no_more_parameters:
stc
finished_scan_cmd_tail:
pop dx
ret
scan_a_non_switch proc near
;scans through a non-switch string or the string following a switch to
;find the end and the length.
push si ;found a non-switch, save beginning
push cx
loop_over_nonswitch_chars:
lodsb ;get next character
dec cx
cmp al,' ' ;see if it's whitespace
je found_end_of_nonswitch
cmp al,tab
je found_end_of_nonswitch
cmp al,'-' ;or maybe it's the beginning of
je found_end_of_nonswitch ;another switch
cmp al,'/'
je found_end_of_nonswitch
cmp al,cr ;check for end of tail
jne loop_over_nonswitch_chars
found_end_of_nonswitch:
dec si
mov current_cmd_tail_position,si ;save our state for next call
inc cl
mov characters_left_in_cmd_tail,cl
mov dx,cx ;get character count
pop cx
sub cx,dx
pop si ;get pointer to beginning of string
dec si
ret
scan_a_non_switch endp
scan_cmd_tail endp
code ends
end begin